#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<time.h>
// 操作类型枚举
typedef enum {
    OP_CREATE_CLASS,    // 创建班级
    OP_ADD_STUDENT,     // 添加学生
    OP_DELETE_STUDENT,  // 删除学生
    OP_UPDATE_STUDENT,  // 修改学生信息
    OP_SEARCH_STUDENT,  // 查询学生
    OP_BACKUP_DATA,     // 备份数据
    OP_RESTORE_DATA     // 恢复数据
} OperationType;
// 链表节点结构
typedef struct Node {
    int index;      // 节点序号（横坐标）
    float score;    // 分数（纵坐标）
    struct Node* next;
} Node;
typedef struct member
{
    char id[5];
    char pwd[8];
    int i;
    int grade;
    int class;
}MEMBER;

typedef struct student
{
    char name[10];
    char id[10];
    char sex;
    int age;
    int grade;
    int class;
    int score[10];
    struct student *next;
}STUDENT;
int check_re_et();
MEMBER * check_rg();
MEMBER * check_et();
void rg_et();
void menu_m(MEMBER *p);
void m_1(MEMBER *p);
void m_1_xuan(MEMBER *p);
STUDENT *m_2(MEMBER *p);
void m_2_xuan(MEMBER *p);
int check_m_2_wei(MEMBER *p,STUDENT *head,FILE *fp,int count);
void check_m_2_wei_t(MEMBER *p,STUDENT *head,FILE *fp,int count);
STUDENT * m_2_tj(STUDENT *head,int a,int count,int i,int j);
const char* get_operation_string(OperationType op);
void log_operation(OperationType op, const char* operator, const char* details);
void plotScoreCurve_GNUplot(Node* head);
int main()
{
    rg_et();
    return 0;
}

int check_re_et()
{
    int flag;
    p:printf("请您选择注册或者登录操作:登录请输入1,注册请输入0,退出请输入-1\n");
    if(scanf("%d",&flag)!=1)
    {
        printf("请输入0或1或-1\n");
        while(getchar()!='\n');
        goto p;
    }
    else if(flag!=1&&flag!=0&&flag!=-1)
    {
        printf("无效选择\n");
        goto p;
    }
    else
    printf("正在进行相关操作-----------");
    return flag;
}
MEMBER * check_rg()
{
    b:MEMBER *p=NULL;
    if((p=(MEMBER*)malloc(2*sizeof(MEMBER)))==NULL)
    {
        printf("在申请账号内存时失败\n");
        exit(-1);
    }
    else
    {
        printf("请输入账号:三位字母\n");
        scanf("%3s",p->id);
        printf("请输入密码:六位数字\n");
        scanf("%6s",p->pwd);
        printf("0为管理员\n1为年级主任\n2为班主任\n3为学生\n请输入您的选择:");
        scanf("%d",&(p->i));
        printf("请输入所属年级和所属班级,管理员所属为0\n");
        scanf("%d%d",&(p->grade),&(p->class));
        if((p->i)==0)
        {
            FILE *f=NULL;
            if((f=fopen("D://code//pwd.txt","ab"))==NULL)
            {
                printf("在创建密码本时失败\n");
                free(p);
                exit(-2);
            }
            FILE *f1=NULL;
            if((f1=fopen("D://code//classif.txt","a"))==NULL)
            {
                printf("在创建班级记录时失败\n");
                free(p);
                exit(-3);
            }
            fclose(f1);
            f1=NULL;
            while(fread(p+1,sizeof(MEMBER),1,f)==1)
            {
                if(strcmp(p->id,(p+1)->id)==0)
                {
                    printf("账号已存在,请重新输入\n");
                    printf("请输入账号:三位字母\n");
                    scanf("%3s",p->id);
                    printf("请输入密码:六位数字\n");
                    scanf("%6s",p->pwd);
                    printf("0为管理员\n1为年级主任\n2为班主任\n3为学生\n请输入您的选择:");
                    scanf("%d",&(p->i));
                    printf("请输入所属年级和所属班级,管理员所属为0\n");
                    scanf("%d%d",&(p->grade),&(p->class));
                    fseek(f,0L,SEEK_SET);
                    continue;
                }
            }
            fseek(f,0L,SEEK_END);
            fwrite(p,sizeof(MEMBER),1,f);
            fclose(f);
            f=NULL;
            int flag1;
            while(1)
            {
                printf("请输入您的下一步操作\n1.继续注册2.登录3.退出系统4.登录别的账号");
                if(scanf("%d",&flag1)!=1)
                {
                    printf("请输入数字\n");
                    while(getchar()!='\n');
                    continue;
                }
                else if(flag1!=1&&flag1!=2&&flag1!=3)
                {
                    printf("无效选项\n");
                    continue;
                }
                else
                {
                    switch(flag1)
                    {
                        case 1:
                        {
                            free(p);
                            goto b;
                        }
                        case 2:
                        {
                            switch(p->i)
                            {
                                case 0:
                                case 1:
                                case 2:
                                case 3:
                            }
                        }
                        case 3:
                        {
                            free(p);
                            exit(0); 
                        }
                        case 4:
                        {
                            p=check_et();
                            switch(p->i)
                            {
                                case 0:
                                case 1:
                                case 2:
                                case 3:
                            }
                        }
                    }
                }
                
            }
            
        }
        else
        {
            FILE *f=NULL;
            if((f=fopen("D://code//pwd.txt","rb+"))==NULL)
            {
                printf("在打开密码本时失败\n");
                free(p);
                exit(-4);
            }
            while(fread(p+1,sizeof(MEMBER),1,f)==1)
            {
                if(strcmp(p->id,(p+1)->id)==0)
                {
                    printf("账号已存在,请重新输入\n");
                    printf("请输入账号:三位字母\n");
                    scanf("%3s",p->id);
                    printf("请输入密码:六位数字\n");
                    scanf("%6s",p->pwd);
                    printf("0为管理员\n1为年级主任\n2为班主任\n3为学生\n请输入您的选择:");
                    scanf("%d",&(p->i));
                    printf("请输入所属年级和所属班级,管理员所属为0\n");
                    scanf("%d%d",&(p->grade),&(p->class));
                    fseek(f,0L,SEEK_SET);
                    continue;
                }
            }
            fseek(f,0L,SEEK_END);
            fwrite(p,sizeof(MEMBER),1,f);
            fclose(f);
            f=NULL;
            int flag1;
            while(1)
            {
                printf("请输入您的下一步操作\n1.继续注册2.登录3.退出系统4.登录别的账号");
                if(scanf("%d",&flag1)!=1)
                {
                    printf("请输入数字\n");
                    while(getchar()!='\n');
                    continue;
                }
                else if(flag1!=1&&flag1!=2&&flag1!=3)
                {
                    printf("无效选项\n");
                    continue;
                }
                else
                {
                    switch(flag1)
                    {
                        case 1:
                        {
                            free(p);
                            goto b;
                        }
                        case 2:
                        {
                            switch(p->i)
                            {
                                case 0:
                                case 1:
                                case 2:
                                case 3:
                            }
                        }
                        case 3:
                        {
                            free(p);
                            exit(0); 
                        }
                        case 4:
                        {
                            p=check_et();
                            switch(p->i)
                            {
                                case 0:
                                case 1:
                                case 2:
                                case 3:
                            }
                        }
                        
                    }
                }
            }
        }
    }
    return p;
}
MEMBER * check_et()
{
    FILE *f=NULL;
    if((f=fopen("D://code//pwd.txt","rb"))==NULL)
    {
        printf("密码本打开失败\n");
        return NULL;
        exit(-5);
    }
    else
    {
        MEMBER *p=NULL;
        if((p=(MEMBER *)malloc(2*sizeof(MEMBER)))==NULL)
        {
            printf("登录时申请内存失败\n");
            exit(-1);
        }
        else
        {
            int count=0;
            while(count<3)
            {
                printf("请输入账号:");
                scanf("%3s",p->id);
                printf("请输入密码:");
                scanf("%6s",p->pwd);
                while(fread(p+1,sizeof(MEMBER),1,f)==1)
                {
                    if((strcmp(p->id,(p+1)->id)==0)&&(strcmp(p->pwd,(p+1)->pwd)==0))
                    {
                        printf("身份验证通过正在进入系统----------\n");
                        goto a;
                    }
                }
                printf("密码或者账号错误!\n");
                count++;
            }
            fclose(f);
            f=NULL;
            printf("密码连续错误三次即将退出系统");
            free(p);
            exit(-6);
        } 
        a:return p;
    }
}
void rg_et()
{
    printf("欢迎进入学生管理系统升级版\n感谢您的使用\n");
    int flag;
    flag=check_re_et();
    switch(flag)
    {
        case 0:
        {   
            MEMBER *p=NULL;
            p=check_rg();
            switch(p->i)
            {
                // case 1:
                // case 2:
                // case 3:
            }    
        }
        case 1:
        {
            MEMBER *p=NULL;
            p=check_et();
            switch(p->i)
            {
                // case 0:
                // case 1:
                // case 2:
                // case 3:
            }
        }
    }
}
void menu_m(MEMBER *p)
{
    while(1)
    {
        int flag;
        c:printf("欢迎您尊敬的管理员先生!\n1.创建班级2.添加学生3.修改学生信息4.删除学生5.查询学生信息6.注册账号7.登录别的账号8.退出系统\n请输入您的选择:");
        if(scanf("%d",&flag)!=1)
        {
            printf("请输入数字\n");
            while(getchar()!='\n');
            goto c;
        }
        else if(flag<1||flag>8)
        {
            printf("无效选项\n");
            goto c;
        }
        else
        {
            switch(flag)
            {
                case 1:
                {
                    m_1(p);
                }
                case 2:m_2(p);
                // case 3:
                // case 4:
                // case 5:
                // case 6:
                // case 7:
                // case 8:
            }
        }
    }
}

void m_1(MEMBER *p)
{
    int i,j,a,b;
    while(1)
    {
        printf("请输入您所要创建的学生年级和班级,年级输入11\n");
        if(scanf("%d%d",&i,&j)!=2)
        {
            printf("请输入数字\n");
            while(getchar()!='\n');
            m_1_xuan(p);
        }
        else if(i%11!=0||j<1)
        {
            printf("输入有误\n");
            m_1_xuan(p);
        }
        else
        {
            FILE *f=NULL;
            if((f=fopen("D://code//classif.txt","ab+"))==NULL)
            {
                printf("班级信息文件打开失败\n");
                free(p);
                exit(-2);
            }
            else
            {
                fseek(f,0L,SEEK_SET);
                while(fread(a,sizeof(int),1,f)&&fread(b,sizeof(int),1,f))
                {
                    if(a==i&&b==j)
                    {
                        printf("文件已经创建无需再次创建\n");
                        fclose(f);
                        menu_m(p);
                    }
                }
                fwrite(i,sizeof(int),1,f);
                fwrite(j,sizeof(int),1,f);
                printf("文件创建完成\n");
                fclose(f);
                menu_m(p);
            }
        }

    }
}

void m_1_xuan(MEMBER *p)
{
    int flag;
    while(1)
    {
        printf("1.继续创建功能 2.返回上级菜单 3.返回注册页面 4.返回登录界面 5.退出系统\n请输入您的下一步操作\n");
        if(scanf("%d",&flag)!='\n')
        {
            printf("请输入数字\n");
            while(getchar()!='\n');
            m_1_xuan(p);
        }
        else if(flag<1||flag>5)
        {
            printf("无效选项\n");
            m_1_xuan(p);
        }
        else
        {
            switch(flag)
            {
                case 1:
                {
                    m_1(p);
                }
                case 2:
                {
                    menu_m(p);
                }
                case 3:
                {
                    check_rg();
                }
                case 4:
                {
                    check_et();
                }
                case 5:
                {
                    free(p);
                    exit(0);
                }
            }

        }
       

    }
}

STUDENT *m_2(MEMBER *p)
{
    int i,j,a,b;
    char c[30]={0}, d[6]={0};
    while(1)
    {
        printf("请输入您所要添加的学生年级和班级,年级输入11\n");
        if(scanf("%d%d",&i,&j)!=2)
        {
            printf("请输入数字\n");
            while(getchar()!='\n');
            m_2_xuan(p);
        }
        else if(i%11!=0||j<1)
        {
            printf("输入有误\n");
            m_2_xuan(p);
        }
        else
        {
            FILE *f=NULL;
            if((f=fopen("D://code//classif.txt","ab+"))==NULL)
            {
                printf("班级信息文件打开失败\n");
                free(p);
                exit(-2);
            }
            else
            {
                fseek(f,0L,SEEK_SET);
                while(fread(a,sizeof(int),1,f)&&fread(b,sizeof(int),1,f))
                {
                    if(a==i&&b==j)
                    {
                        fclose(f);
                        FILE *fp=NULL;
                        sprintf(d,"%d%d",i,j);
                        strcat(strcat(strcpy(a,"D://code//"),d),".txt");
                        if((fp=fopen(a,"ab+"))==NULL)
                        {
                            printf("班级数据读取失败\n");
                            free(p);
                            exit(-8);
                        }
                        else
                        {
                            STUDENT *head=NULL,*pt=NULL,*prept=NULL;
                            int count=0;
                            if((head=(STUDENT*)malloc(sizeof(STUDENT)))==NULL)
                            {
                                printf("在申请学生信息内存时失败\n");
                                free(p);
                                fclose(fp);
                            }
                            else
                            {
                                pt=head;
                                while(fread(pt,sizeof(STUDENT),1,fp))
                                {
                                    prept=head;
                                    if((head=realloc(head,(count+2)*sizeof(STUDENT)))==NULL)
                                    {
                                        printf("动态内存增长失败\n");
                                        free(prept);
                                        free(p);
                                        fclose(fp);
                                        exit(-5);
                                    }
                                    else
                                    {
                                        if(head=prept)
                                        {
                                            pt->next=++pt;
                                            pt->next=NULL;
                                        }
                                        else
                                        {
                                            pt->next=head+count+1;
                                            pt=pt->next;
                                            pt->next=NULL;
                                        }
                                    }
                                    count++;
                                }
                                int wei;
                                wei=check_m_2_wei(p,head,fp,count);
                                STUDENT *tou=NULL,*qw=NULL;
                                tou=m_2_tj(head,wei,count,i,j);
                                qw=tou;
                                fclose(fp);
                                fp=fopen(a,"wb+");
                                while(tou!=NULL)
                                {
                                    fwrite(tou,sizeof(STUDENT),1,fp);
                                    tou=tou->next;
                                }
                                printf("已自动保存\n");
                                fclose(fp);
                                fp=NULL;
                                free(qw);
                                m_2_xuan(p);
                            }

                        }
                        
                    }
                }
            }
        }
    }
}

void m_2_xuan(MEMBER *p)
{
    int flag;
    while(1)
    {
        printf("1.继续添加功能 2.返回上级菜单 3.返回注册页面 4.返回登录界面 5.退出系统\n请输入您的下一步操作\n");
        if(scanf("%d",&flag)!='\n')
        {
            printf("请输入数字\n");
            while(getchar()!='\n');
            m_2_xuan(p);
        }
        else if(flag<1||flag>5)
        {
            printf("无效选项\n");
            m_2_xuan(p);
        }
        else
        {
            switch(flag)
            {
                case 1:
                {
                    m_2(p);
                }
                case 2:
                {
                    menu_m(p);
                }
                case 3:
                {
                    check_rg();
                }
                case 4:
                {
                    check_et();
                }
                case 5:
                {
                    free(p);
                    exit(0);
                }
            }

        }

    }
}

int check_m_2_wei(MEMBER *p,STUDENT *head,FILE *fp,int count)
{
    int a;
    while(1)
    {
        printf("1~%d\n请输入您所要添加的位置:",count+1);
        if(scanf("%d",&a)!=1)
        {
            printf("请输入数字\n");
            while(getchar()!='\n');
            check_m_2_wei_t(p,head,fp,count);
        }
        else if(a<1||a>count+1)
        {
            printf("无效位置\n");
            check_m_2_wei_t(p,head,fp,count);
        }
        else;
        return a; 
    }
}
void check_m_2_wei_t(MEMBER *p,STUDENT *head,FILE *fp,int count)
{
    int a;
    while(1)
    {
        printf("1.返回上级菜单 2.重新选择位置3.返回登录界面4.返回注册界面5.退出系统\n请输入您的下一步操作:");
        if(scanf("%d",&a)!=1)
        {
            printf("请输入数字\n");
            while(getchar()!='\n');
            check_m_2_wei_t(p,head,fp,count);
        }
        else if(a<1||a>5)
        {
            printf("无效选项\n");
            check_m_2_wei_t(p,head,fp,count);
        }
        else
        {
            switch(a)
            {
                case 1:
                {
                    free(head);
                    fclose(fp);
                    menu_m(p);
                }
                case 2:
                {
                    check_m_2_wei(p,head,fp,count);
                }
                case 3:
                {
                    free(p);
                    free(head);
                    fclose(fp);
                    check_et();
                }
                case 4:
                {
                    free(p);
                    free(head);
                    fclose(fp);
                    check_rg();
                }
                case 5:
                {
                    free(p);
                    free(head);
                    fclose(fp);
                    exit(0);
                }
            }
        }
    }
}

STUDENT * m_2_tj(STUDENT *head,int a,int count,int i,int j)
{
    if(a==1)
    {
        printf("请输入学生姓名\n");
        scanf("%s",(head+count)->name);
        printf("请输入学生学号\n");
        scanf("%s",(head+count)->id);
        printf("请输入学生性别\n");
        scanf("% c",&(head+count)->sex);
        printf("请输入学生年龄\n");
        scanf("%d",&(head+count)->age);
        for(int k=0;k<10;k++)
        {
            printf("请输入学生第%d门成绩成绩\n",k+1);
            scanf("%d",&(head+count)->score[k]);
        }
        (head+count)->grade=i%10;
        (head+count)->class=j;
        (head+count)->next=head;
        (head+count-1)->next=NULL;
        return head+count;
    }
    else if(a==count+1)
    {
        printf("请输入学生姓名\n");
        scanf("%s",(head+count)->name);
        printf("请输入学生学号\n");
        scanf("%s",(head+count)->id);
        printf("请输入学生性别\n");
        scanf("% c",&(head+count)->sex);
        printf("请输入学生年龄\n");
        scanf("%d",&(head+count)->age);
        for(int k=0;k<10;k++)
        {
            printf("请输入学生第%d门成绩成绩\n",k+1);
            scanf("%d",&(head+count)->score[k]);
        }
        (head+count)->grade=i%10;
        (head+count)->class=j;
        return head;
    }
    else
    {
        printf("请输入学生姓名\n");
        scanf("%s",(head+count)->name);
        printf("请输入学生学号\n");
        scanf("%s",(head+count)->id);
        printf("请输入学生性别\n");
        scanf("% c",&(head+count)->sex);
        printf("请输入学生年龄\n");
        scanf("%d",&(head+count)->age);
        for(int k=0;k<10;k++)
        {
            printf("请输入学生第%d门成绩成绩\n",k+1);
            scanf("%d",&(head+count)->score[k]);
        }
        (head+count)->grade=i%10;
        (head+count)->class=j;
        STUDENT *q=NULL,*w=NULL;
        q=head+a-1;
        w=head+a;
        (head+count)->next=w;
        q->next=head+count;
        return head;
    }

}


// 获取操作类型字符串
const char* get_operation_string(OperationType op) {
    switch(op) {
        case OP_CREATE_CLASS:   return "创建班级";
        case OP_ADD_STUDENT:    return "添加学生";
        case OP_DELETE_STUDENT: return "删除学生";
        case OP_UPDATE_STUDENT: return "修改学生";
        case OP_SEARCH_STUDENT: return "查询学生";
        case OP_BACKUP_DATA:    return "备份数据";
        case OP_RESTORE_DATA:   return "恢复数据";
        default:                return "未知操作";
    }
}

// 记录操作日志
void log_operation(OperationType op, const char* operator, const char* details) {
    time_t rawtime;
    struct tm* timeinfo;
    char timestamp[64];
    FILE* logfile;
    
    // 获取当前时间
    time(&rawtime);
    timeinfo = localtime(&rawtime);
    strftime(timestamp, sizeof(timestamp), "%Y-%m-%d %H:%M:%S", timeinfo);
    
    // 打开日志文件
    logfile = fopen("student_system.log", "a");
    if (logfile == NULL) {
        printf("无法打开日志文件！\n");
        return;
    }
    
    // 写入日志
    fprintf(logfile, "[%s] 操作员:%s | 操作:%s | 详情:%s\n", 
            timestamp, operator, get_operation_string(op), details);
    
    fclose(logfile);
    
    // 同时在控制台显示（可选）
    printf("[%s] %s: %s - %s\n", timestamp, operator, get_operation_string(op), details);
}

void plotScoreCurve_GNUplot(Node* head) {
    if (head == NULL) {
        printf("链表为空，无法绘图\n");
        return;
    }
    
    // 创建临时数据文件
    FILE* dataFile = fopen("score_data.txt", "w");
    if (dataFile == NULL) {
        printf("无法创建数据文件\n");
        return;
    }
    
    // 写入链表数据
    Node* current = head;
    while (current != NULL) {
        fprintf(dataFile, "%d %.2f\n", current->index, current->score);
        current = current->next;
    }
    fclose(dataFile);
    
    // 创建GNUplot脚本
    FILE* script = fopen("plot_score.plt", "w");
    if (script == NULL) {
        printf("无法创建脚本文件\n");
        return;
    }
    
    fprintf(script, "set title '分数变化曲线图'\n");
    fprintf(script, "set xlabel '序号'\n");
    fprintf(script, "set ylabel '分数'\n");
    fprintf(script, "set grid\n");
    fprintf(script, "set xrange [0:*]\n");
    fprintf(script, "set yrange [0:100]\n");
    fprintf(script, "plot 'score_data.txt' with linespoints linecolor 'blue' pointtype 7 pointsize 1 title '分数曲线'\n");
    fprintf(script, "pause -1 '按任意键关闭图表...'\n");
    fclose(script);
    
    // 执行GNUplot
    system("gnuplot plot_score.plt");
    
    // 清理临时文件
    remove("score_data.txt");
    remove("plot_score.plt");
    
    printf("曲线图绘制完成！\n");
}